package com.ybkj.daijia.server.controller;


import com.ybkj.daijia.Setting;
import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.common.IsMainCompany;
import com.ybkj.daijia.common.Principal;
import com.ybkj.daijia.common.Result;
import com.ybkj.daijia.server.exception.NoPermissionException;
import com.ybkj.daijia.page.Page;
import com.ybkj.daijia.server.event.model.OperationLogEvent;
import com.ybkj.daijia.server.model.Admin;
import com.ybkj.daijia.server.model.Company;
import com.ybkj.daijia.server.model.Role;
import com.ybkj.daijia.server.service.AdminService;
import com.ybkj.daijia.server.service.CompanyService;
import com.ybkj.daijia.server.service.RoleService;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;


/**
 * @author Shine
 */
@Controller
@RequestMapping(value = "admin")
public class AdminController {

    @Autowired
    private SettingUtils settingUtils;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private AdminService adminService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private CompanyService companyService;

    @Autowired
    private ApplicationEventMulticaster applicationEventMulticaster;

    @RequestMapping(value = "list", method = RequestMethod.GET)
    public ModelAndView list(@RequestParam(required = false, value = "name") String name) {

        Subject subject = SecurityUtils.getSubject();
        Principal principal = (Principal) subject.getPrincipal();
        //主公司才有系统账号管理权限
//		if(subject.isPermitted("account")  && IsMainCompany.isMain()){
        //分公司拥有管理本公司系统账号的权限
        if (subject.isPermitted("account")) {
            ModelAndView mv = new ModelAndView();
            Page<Admin> page = null;
            mv.setViewName("admin/list");

            if (null != principal) {
                if (principal.isCompanyType()) {
                    page = adminService.selectByPage(null, name);
                } else {
                    page = adminService.selectByPage(principal.getCompanyId(), name);
                }
            }
            mv.addObject("page", page);
            mv.addObject("name", name);
            return mv;
        } else {
            throw new NoPermissionException();
        }

    }

    @RequestMapping(value = "add", method = RequestMethod.GET)
    public ModelAndView add(HttpSession session) {
        Subject subject = SecurityUtils.getSubject();
        Principal principal = (Principal) subject.getPrincipal();
        //主公司拥有创建账号的权限
//		if(subject.isPermitted("account")  && IsMainCompany.isMain()){
        //分公司创建属于自己公司的账号
        if (subject.isPermitted("account")) {
            ModelAndView mv = new ModelAndView();
            List<Role> roleList = new ArrayList<>();
            List<Company> companyList = new ArrayList<>();
            if (null != principal) {
                //主公司
                if (principal.isCompanyType()) {
                    roleList = roleService.listByCompanyId(null);
                    companyList = companyService.findAll();
                } else {
                    roleList = roleService.listByCompanyId(principal.getCompanyId());
                    companyList.add(companyService.findOne(principal.getCompanyId()));
                }
            }
            mv.addObject("roles", roleList);
            mv.addObject("companys", companyList);
            mv.addObject("admin", new Admin());

            mv.setViewName("admin/add");

            return mv;
        } else {
            throw new NoPermissionException();
        }

    }

    @RequestMapping(value = "create", method = RequestMethod.POST)
    public String create(Admin admin, Long[] roleIds, Long companyid, Model model) {

        Subject subject = SecurityUtils.getSubject();
        Principal principal = (Principal) subject.getPrincipal();
        Setting setting = settingUtils.get();
//		String webUrl = StringUtils.substringBefore(setting.getWebUrl(),"t:8080");
//		String referer = StringUtils.substringBefore(request.getHeader("Referer"),"t:8080");
        if (subject.isPermitted("account")) {

//			if(!webUrl.equals(referer)){
//				return "500";
//			}

            if (exists(admin.getUsername(), null)) {
                model.addAttribute("message", "用户名'" + admin.getUsername() + "'已存在");
                model.addAttribute("roles", roleService.findAll());
                model.addAttribute("companys", companyService.findAll());
                model.addAttribute("admin", admin);
                return "admin/add";
            }

            if (admin.getIsLocked()) {
                admin.setIsLocked(Boolean.TRUE);
            } else {
                admin.setIsLocked(Boolean.FALSE);
            }

            Sha256Hash hash = new Sha256Hash(admin.getPassword(), Admin.SALT_KEY);
            admin.setPassword(hash.toBase64());

            admin.setIsInternal(false);
            admin.setCompanyId(companyid);
            admin.setPasswordDate(new Date());

            adminService.insertAdmin(admin, roleIds);

            String detail = "【%s】新增了用户【" + admin.getUsername() + "】";
            OperationLogEvent operationLogEvent = new OperationLogEvent(principal, detail);
            applicationEventMulticaster.multicastEvent(operationLogEvent);

            return "redirect:list";
        } else {
            throw new NoPermissionException();
        }

    }

    @RequestMapping(value = "edit/{id}", method = RequestMethod.GET)
    public ModelAndView edit(@PathVariable("id") Long id) {
        Subject subject = SecurityUtils.getSubject();

        if (subject.isPermitted("account")) {
            ModelAndView mv = new ModelAndView();
            List<Role> roleList = new ArrayList<>();
            Admin local = adminService.findOne(id);
            local.setRoles(roleService.findByAdmin(local.getId()));
            Principal principal = (Principal) subject.getPrincipal();
            if (null != principal) {
                if (principal.isCompanyType()) {
                    roleList = roleService.listByCompanyId(null);
                } else {
                    roleList = roleService.listByCompanyId(principal.getCompanyId());
                }
            }
            mv.addObject("roles", roleList);
            mv.addObject("companys", companyService.findAll());
            mv.addObject("admin", local);

            mv.setViewName("admin/edit");

            return mv;
        } else {
            throw new NoPermissionException();
        }

    }

    @RequestMapping(value = "update", method = RequestMethod.POST)
    public String update(Admin admin, Long[] roleIds, Long companyid) {

        Subject subject = SecurityUtils.getSubject();
        Principal principal = (Principal) subject.getPrincipal();
        Setting setting = settingUtils.get();
        String webUrl = setting.getWebUrl() + "/admin/add";
        String referer = request.getHeader("Referer");
        if (subject.isPermitted("account") && IsMainCompany.isMain()) {
            Admin local = adminService.findOne(admin.getId());

            //内置只能改密码
            if (local.getIsInternal()) {
                if (StringUtils.isEmpty(admin.getPassword())) {
                    //未修改密码
                } else {
                    //修改密码
                    Sha256Hash hash = new Sha256Hash(admin.getPassword(), Admin.SALT_KEY);
                    local.setPassword(hash.toBase64());
                    local.setCompanyId(companyid);
                    local.setPasswordDate(new Date());
                    adminService.updateByPrimaryKey(local);
                }

                String detail = "【%s】修改了用户【" + local.getUsername() + "】";
                OperationLogEvent operationLogEvent = new OperationLogEvent(principal, detail);
                applicationEventMulticaster.multicastEvent(operationLogEvent);

                return "redirect:list";
            }

//			if(admin.getIsLocked()){
//				local.setIsLocked(Boolean.TRUE);
//			}
//			else{
//				local.setIsLocked(Boolean.FALSE);
//			}

            if (StringUtils.isEmpty(admin.getPassword())) {
                //未修改密码
            } else {
                //修改密码
                Sha256Hash hash = new Sha256Hash(admin.getPassword(), Admin.SALT_KEY);
                local.setPassword(hash.toBase64());
                local.setPasswordDate(new Date());
            }

            local.setPhone(admin.getPhone());
            local.setPhoneLogin(admin.isPhoneLogin());
            local.setCompanyId(companyid);
            adminService.updateByPrimaryKey(local, roleIds);

            String detail = "【%s】修改了用户【" + local.getUsername() + "】";
            OperationLogEvent operationLogEvent = new OperationLogEvent(principal, detail);
            applicationEventMulticaster.multicastEvent(operationLogEvent);

            return "redirect:list";
        } else {
            throw new NoPermissionException();
        }

    }

    @RequestMapping(value = "delete", method = RequestMethod.POST)
    public @ResponseBody
    Result<Integer> delete(Long id) {

        Subject subject = SecurityUtils.getSubject();
        Principal principal = (Principal) subject.getPrincipal();

        if (subject.isPermitted("account") && IsMainCompany.isMain()) {
            Result<Integer> result = new Result<Integer>();
            Admin admin = adminService.findOne(id);

            if (admin.getIsInternal()) {
                result.setSuccess(false);
                result.setMessage("'" + admin.getUsername() + "'为系统内置，不能删除");
                return result;
            }

            String detail = "【%s】删除了用户【" + admin.getUsername() + "】";

            adminService.delete(admin);
            result.setSuccess(true);

            OperationLogEvent operationLogEvent = new OperationLogEvent(principal, detail);
            applicationEventMulticaster.multicastEvent(operationLogEvent);

            return result;
        } else {
            throw new NoPermissionException();
        }

    }

    @RequestMapping(value = "unlock", method = RequestMethod.POST)
    public @ResponseBody
    Result<Integer> unlockAdmin(Long id) {

        Subject subject = SecurityUtils.getSubject();
        Principal principal = (Principal) subject.getPrincipal();

        if (subject.isPermitted("account")) {
            Result<Integer> result = new Result<Integer>();
            Admin admin = adminService.findOne(id);

            String detail = "【%s】解锁了用户【" + admin.getUsername() + "】";

            adminService.unLockUser(id);
            result.setSuccess(true);

            OperationLogEvent operationLogEvent = new OperationLogEvent(principal, detail);
            applicationEventMulticaster.multicastEvent(operationLogEvent);

            return result;
        } else {
            throw new NoPermissionException();
        }

    }


    @RequestMapping(value = "checkLoginToken", method = RequestMethod.GET)
    public @ResponseBody
    Result<Admin> checkLoginToken() {
        Result<Admin> result = new Result<>();

        Subject subject = SecurityUtils.getSubject();
        Principal principal = (Principal) subject.getPrincipal();

        Admin admin = adminService.findOne(principal.getId());

        if (StringUtils.isBlank(principal.getLoginToken()) || StringUtils
            .isBlank(admin.getLoginToken())) {
            result.setSuccess(false);
            return result;
        }

        if (!principal.getLoginToken().equals(admin.getLoginToken())) {
            result.setSuccess(false);
            return result;
        }

        result.setSuccess(true);
        return result;
    }

    public boolean exists(String username, Long id) {

        Admin admin = adminService.findByUsername(username);

        if (null != admin) {

            if (null != id && id.equals(admin.getId())) {

                return false;

            }

            return true;
        }

        return false;
    }

}

